import { AfterViewInit, Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { DeptDto } from 'src/app/models/sys/dept.dto';
import { ApiService } from 'src/app/services/api.service';
import { DeptQueryParam } from 'src/app/models/param/dept-query.param';
import { Consts } from 'src/app/consts/consts';
import { FormBuilder, FormControl, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { NzTreeNodeOptions } from 'ng-zorro-antd/tree';
import { AddDeptParam } from 'src/app/models/param/add-dept.param';
import { NzMessageService } from 'ng-zorro-antd/message';
import { BehaviorSubject } from 'rxjs';
import { EditMode } from 'src/app/models/enums/edit-mode.enum';
import { UpdateDeptParam } from 'src/app/models/param/update-dept.param';

const PARENT_ID = 'parentId';
const DEPT_NAME = 'deptName';
const CODE = 'code';
const ORDER_NUM = 'orderNum';
const LEADER = 'leader';
const PHONE_NUMBER = 'phoneNumber';
const EMAIL = 'email';

@Component({
  selector: 'app-add-dept',
  templateUrl: './add-dept.component.html',
  styleUrl: './add-dept.component.less'
})
export class AddDeptComponent implements OnInit, AfterViewInit {
  @Input() modeSubject!: BehaviorSubject<{ mode: EditMode, dept?: DeptDto, parentId?: number }>;
  @Output() addDeptEvent = new EventEmitter<boolean>();

  // 新建还是编辑
  dept?: DeptDto;
  modeEnum = EditMode;
  editMode = EditMode.ADD;
  parentValue?: string = '0';

  // form fields
  addForm!: UntypedFormGroup;
  submitted = false;

  // Tree table
  depts: DeptDto[] = [];
  deptNodes: NzTreeNodeOptions[] = [];
  pageIndex = 1;
  pageSize = 10;
  total = 0;
  selectedNode?: string;


  expandKeys = [];

  constructor(private _api: ApiService,
    private _fb: FormBuilder,
    private _message: NzMessageService) { }

  ngOnInit(): void {
    this.createAddForm();
  }

  ngAfterViewInit(): void {
    setTimeout(() => {
      this.getDepts();
    });
  }

  createAddForm() {
    this.addForm = this._fb.group({});
    this.addForm.addControl(PARENT_ID, new UntypedFormControl(0));
    this.addForm.addControl(DEPT_NAME, new UntypedFormControl('', [Validators.minLength(2), Validators.maxLength(45)]));
    this.addForm.addControl(CODE, new UntypedFormControl('', [Validators.minLength(2), Validators.maxLength(45)]));
    this.addForm.addControl(ORDER_NUM, new UntypedFormControl(1, [Validators.min(1), Validators.max(10000)]));
    this.addForm.addControl(LEADER, new UntypedFormControl('', [Validators.minLength(2), Validators.maxLength(20)]));
    this.addForm.addControl(PHONE_NUMBER, new UntypedFormControl('', [Validators.minLength(11), Validators.maxLength(11)]));
    this.addForm.addControl(EMAIL, new UntypedFormControl('', [Validators.email]));

    this.modeSubject.subscribe((value) => {
      this.editMode = value.mode;
      console.log(`dept modal with mode ${this.editMode}`);

      if (this.editMode == EditMode.ADD) {
        this.addForm.get(DEPT_NAME)?.addValidators([Validators.required]);

        if (value.parentId != null) {
          console.log(`add with parentId ${value.parentId}`);
          this.parentValue = String(value.parentId!);
        }
      } else {
        this.dept = value.dept;
        this.initParam(this.dept!);
      }
    })
  }

  initParam(dept: DeptDto) {
    this.parentValue = String(dept.parentId);

    this.addForm.get(DEPT_NAME)?.patchValue(dept.deptName);
    this.addForm.get(CODE)?.patchValue(dept.code);
    this.addForm.get(ORDER_NUM)?.patchValue(dept.orderNum);
    this.addForm.get(LEADER)?.patchValue(dept.leader);
    this.addForm.get(PHONE_NUMBER)?.patchValue(dept.phoneNumber);
    this.addForm.get(EMAIL)?.patchValue(dept.email);
  }

  getDepts() {
    const param = new DeptQueryParam();
    param.pageNum = 1;
    param.pageSize = 10000;
    this._api.getDeptTree(param).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK && resp.data) {
        this.depts = resp.data;
        this.total = resp.total;
        this.convertToTreeNodes(this.depts);
      }
    });
  }

  convertToTreeNodes(depts: DeptDto[]) {
    this.deptNodes = [];

    for (const dept of depts) {

      const node = this.convertToTreeNode(dept);
      // console.log(`convert parent ${node.key}`);
      this.deptNodes.push(node);
    }
  }

  convertToTreeNode(dept: DeptDto): NzTreeNodeOptions {
    const result: NzTreeNodeOptions = {
      title: dept.deptName,
      key: dept.deptId.toString(),
    }

    const nodeChildren: NzTreeNodeOptions[] = [];
    if (dept.children) {
      for (const child of dept.children) {
        const nodeChild = this.convertToTreeNode(child);
        // console.log(`add child ${nodeChild.key} to parent ${result.key}`);
        nodeChildren.push(nodeChild);
      }
      result.children = nodeChildren;
    }

    return result;
  }

  onChange($event: string): void {
    const selected = this.addForm.get('parentId');
    console.log(`selected node ${selected} with event ${$event}`);
  }

  get fm() {
    return this.addForm.controls;
  }

  onCreate() {
    console.log('onAdd');
    this.submitted = true;
    if (this.addForm.invalid) {
      console.log('form error');
      return;
    }

    const param = new AddDeptParam();
    param.parentId = Number(this.parentValue);
    param.deptName = this.addForm.get('deptName')!.value;
    param.code = this.addForm.get('code')!.value;
    param.leader = this.addForm.get('leader')?.value;
    param.phoneNumber = this.addForm.get('phoneNumber')?.value;

    this._api.addDept(param).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK) {
        const result = resp.data;
        if (result) {
          this._message.info("添加部门成功");
          this.onReset();
          this.addDeptEvent.emit(true);
        } else {
          this._message.warning("添加部门错误 " + resp.message);
        }
      }
    });
  }

  onUpdate() {
    this.submitted = true;
    if (this.dept == null) {
      this._message.warning("没有选中部门");
      return;
    }

    const param = new UpdateDeptParam();
    param.deptId = this.dept!.deptId;

    param.parentId = this.addForm.get(PARENT_ID)?.dirty ? this.addForm.get(PARENT_ID)?.value : undefined;
    param.deptName = this.addForm.get(DEPT_NAME)?.dirty ? this.addForm.get(DEPT_NAME)?.value : undefined;
    param.orderNum = this.addForm.get(ORDER_NUM)?.dirty ? this.addForm.get(ORDER_NUM)?.value : undefined;
    param.code = this.addForm.get(CODE)?.dirty ? this.addForm.get(CODE)?.value : undefined;
    param.leader = this.addForm.get(LEADER)?.dirty ? this.addForm.get(LEADER)?.value : undefined;
    param.phoneNumber = this.addForm.get(PHONE_NUMBER)?.dirty ? this.addForm.get(PHONE_NUMBER)?.value : undefined;
    param.email = this.addForm.get(EMAIL)?.dirty ? this.addForm.get(EMAIL)?.value : undefined;

    console.log(`onUpdate dept with ${param.deptId}`);
    this._api.updateDept(param).subscribe((resp) => {
      if (resp.code == Consts.RESP_OK) {
        this._message.info("更新成功");
        this.addDeptEvent.emit(true);
      } else {
        this._message.warning("更新错误: " + resp.message);
        this.addDeptEvent.emit(false);
      }
      this.onReset();
    });
  }

  onSubmit(event: UIEvent) {
    event.preventDefault();

    console.log(`on submit with mode ${this.editMode}`);
    if (this.editMode == EditMode.ADD) {
      this.onCreate();
    } else {
      this.onUpdate();
    }
  }

  onCancel(event: UIEvent) {
    event.preventDefault();
    console.log('onCancel');
    this.onReset();
    this.addDeptEvent.emit(false);
  }

  onReset() {
    this.dept = undefined;
    this.editMode = EditMode.ADD;
    this.parentValue = '0';
    this.submitted = false;
    this.depts = [];
    this.deptNodes = [];
    this.selectedNode = undefined;
    this.expandKeys = [];
  }
}
